/*********************************************************************************
  *Copyright(C),2015-2020,
  *TUYA
  *www.tuya.comm
  *FileName:    tuya_ipc_motion_detect_demo
**********************************************************************************/

#include <stdio.h>
#include "tuya_ipc_cloud_storage.h"
#include "tuya_ipc_stream_storage.h"
#include "tuya_ipc_api.h"
#include "tuya_ipc_event.h"
#include "tuya_ipc_ai_detect_storage.h"
#include "tuya_ipc_media_demo.h"
#include "tuya_ipc_motion_detect_demo.h"
#include "SdkMotionDetectRecord.h"
#include "InSdkIniBasic.h"
#include "InSdkIniDev.h"

#define DEF_TAG             "MDFunc"

#define DEF_MD_NOTHING_IS_MOVING_TIME       (10 + 1)

Com_u8 g_TuyaMotionDetect_Start = DEF_COM_FALSE;
Com_u8 g_TuyaMotionDetect_Reset = DEF_COM_FALSE;
Com_s32 g_TuyaMotionDetect_Interval = 120;
Com_s32 g_TuyaMotionDetect_Sensitivity = 0;

void Ext_TuyaMD_SetFlag(Com_u8 flag)
{
    g_TuyaMotionDetect_Start = flag;
    if(flag == DEF_COM_TRUE)
    {
        g_TuyaMotionDetect_Reset = DEF_COM_TRUE;
    }
}

Com_u8 Ext_TuyaMD_GetFlag(void)
{
    return g_TuyaMotionDetect_Start;
}

Com_void Ext_TuyaMD_Reset(Com_void)
{
    g_TuyaMotionDetect_Reset = DEF_COM_TRUE;
}

void Ext_TuyaMD_SetSensitivity(Com_s32 mode)
{
    g_TuyaMotionDetect_Sensitivity = mode;
}

void Ext_TuyaMD_SetInterval(INT_T val)
{
    g_TuyaMotionDetect_Interval = (val * 60);
}

//According to different chip platforms, users need to implement the interface of capture.
VOID tuya_ipc_get_snapshot_cb(char* pjbuf,int *size)
{
    //get_motion_snapshot(pjbuf,size);
}

Com_s32 TuyaSdkMD_CheckTime(Com_void)
{
    Com_u8 enable_md_time;
    Com_u8 over_24h_flag = DEF_COM_FALSE;
    Com_u8 working_time_flag = DEF_COM_FALSE;
    Com_s8 md_work_time[12];
    StComCurrentTime cur_clock;

    memset(&cur_clock,0,sizeof(cur_clock));
    memset(md_work_time,0,sizeof(md_work_time));

    UnInSdkIniCfgKeyData udata;
    memset(&udata, 0, sizeof(udata));

    Ext_InSdkIniIot_GetData(INI_DEV_INT_MD_TIME_SWITCH, &udata);
    enable_md_time = udata.val;
    if(enable_md_time == 0)
    {
        return DEF_COM_SUCCESS;
    }

    memset(&udata, 0, sizeof(udata));
    Ext_InSdkIniIot_GetData(INI_DEV_STR_MOTION_TIME,&udata);
    strcpy(md_work_time,udata.str);

    if(strstr(md_work_time,"00002359") == NULL)
    {
        Com_s32 s_hour = Ext_InComStrHandle_Byte2Int(md_work_time[0]) * 10 + Ext_InComStrHandle_Byte2Int(md_work_time[1]);
        Com_s32 s_min = Ext_InComStrHandle_Byte2Int(md_work_time[2]) * 10 + Ext_InComStrHandle_Byte2Int(md_work_time[3]);
        Com_s32 e_hour = Ext_InComStrHandle_Byte2Int(md_work_time[4]) * 10 + Ext_InComStrHandle_Byte2Int(md_work_time[5]);
        Com_s32 e_min = Ext_InComStrHandle_Byte2Int(md_work_time[6]) * 10 + Ext_InComStrHandle_Byte2Int(md_work_time[7]);
        Com_s32 s_sec = (s_hour * 60 * 60) + (s_min * 60);
        Com_s32 e_sec = (e_hour * 60 * 60) + (e_min * 60);
        Com_s32 g_sec = 0;

        if(s_hour > e_hour)
        {
            over_24h_flag = DEF_COM_TRUE;
        }
        else if((s_hour == e_hour) && (s_min >= e_min))
        {
            over_24h_flag = DEF_COM_TRUE;
        }

        Ext_InComTimer_GetLocalTime(&cur_clock);
        g_sec = (cur_clock.hour * 60 * 60) + (cur_clock.min * 60);

        if(over_24h_flag == DEF_COM_TRUE)
        {
            if((g_sec >= s_sec) || (g_sec <= e_sec))
            {
                working_time_flag = DEF_COM_TRUE;
            }
        }
        else
        {
            if((g_sec >= s_sec) && (g_sec <= e_sec))
            {
                working_time_flag = DEF_COM_TRUE;
            }
        }
    }
    else
    {
        /* all time */
        working_time_flag = DEF_COM_TRUE;
    }


    if(working_time_flag == DEF_COM_TRUE)
    {
        return DEF_COM_SUCCESS;
    }
    else /* working_time_flag == DEF_COM_FALSE */
    {
        return DEF_COM_FAILED;
    }
}

VOID *thread_md_proc(VOID *arg)
{
    int motion_alarm_is_triggerd = FALSE;
    int snap_size = 0;
    int ret = -1;
    char snap_addr[MAX_SNAPSHOT_BUFFER_SIZE];
    int total_cnt = 0;
    Com_s32 stop_cloud_storage_cnt;
    StComSecondTimer cur_md_time;
    StComSecondTimer get_res_time;

    memset(&cur_md_time,0,sizeof(cur_md_time));
    memset(&get_res_time,0,sizeof(get_res_time));

    ret = Ext_SdkMotionDetect_Init();
    if (ret != 0)
    {
        printf("motion detect init failed!\n");
        return NULL;
    }

    /* init get_res_time */
    Ext_InComTimer_GetSec(DEF_COM_SET_NEW_TIME,&get_res_time);

    DEF_COM_SET_THREAD_NAME("Motion_Detect",g_ComThread_Num);

    while (g_ComThread_Running)
    {
        if (g_TuyaMotionDetect_Start == DEF_COM_FALSE)
        {
            sleep(1);
            continue;
        }

        if(Ext_SdkMediaCom_GetSleepMode() == DEF_COM_TRUE)
        {
            usleep(50 * 1000);
            continue;
        }

        if (DEF_COM_TRUE == Ext_SdkMediaCom_GetMdResult())
        {
            total_cnt++;
            if (total_cnt >= (8 - g_TuyaMotionDetect_Sensitivity * 2))
            {
                memset(snap_addr,0,sizeof(snap_addr));

                Ext_SdkMediaCom_SavePic();
                Ext_SdkMediaCom_GetMDSnapshot(snap_addr,&snap_size);
                if(snap_size > 0)
                {
                    motion_alarm_is_triggerd = TRUE;
                    /* app ctrl  motion_detect_flag */
                    if (g_TuyaMotionDetect_Start == DEF_COM_TRUE)
                    {
                        tuya_ipc_notify_alarm(snap_addr, snap_size, NOTIFICATION_NAME_MOTION, 1);
                    }
                    Ext_SdkMotionDetectRecord_SetMode(START_EVENT_RECORD);
                    tuya_ipc_start_storage(E_ALARM_CLOUD_STORAGE);
                }
                else
                {
                    sleep(5);
                    continue;
                }

                PRT_INFO(DEF_TAG,"waiting for motion detect\n");
                total_cnt = 0;
                stop_cloud_storage_cnt = 0;
                g_TuyaMotionDetect_Reset = DEF_COM_FALSE;
                Ext_InComTimer_GetSec(DEF_COM_SET_NEW_TIME,&cur_md_time);

                while (DEF_COM_TRUE)
                {
                    if(Ext_InComFile_Access(DEF_DP_ENABLE_SD_RECORD) == DEF_COM_FILE_NOT_EXIST)
                    {
                        if(motion_alarm_is_triggerd)
                        {
                            Ext_SdkMotionDetectRecord_SetMode(STOP_EVENT_RECORD);
                        }
                    }

                    if(g_TuyaMotionDetect_Reset == DEF_COM_TRUE)
                    {
                        PRT_WARN(DEF_TAG,"md reset again\n");
                        g_TuyaMotionDetect_Reset = DEF_COM_FALSE;
                        break;
                    }

                    /* timeout check  */
                    if (Ext_InComTimer_GetSec(DEF_COM_NOT_SET_TIME,&cur_md_time) >= (g_TuyaMotionDetect_Interval))
                    {
                        PRT_INFO(DEF_TAG,"timeout of motion detect\n");
                        break;
                    }

                    if ((stop_cloud_storage_cnt >= DEF_MD_NOTHING_IS_MOVING_TIME) &&
                        motion_alarm_is_triggerd)
                    {
                        PRT_INFO(DEF_TAG,"no motion detect\n");
                        motion_alarm_is_triggerd = FALSE;
                        Ext_SdkMotionDetectRecord_SetMode(STOP_EVENT_RECORD);
                        tuya_ipc_stop_storage(E_ALARM_CLOUD_STORAGE);
                    }

                    /* no motion detect */
                    if(DEF_COM_TRUE != Ext_SdkMediaCom_GetMdResult())
                    {
                        stop_cloud_storage_cnt++;
                    }
                    sleep(1);
                }

                if(motion_alarm_is_triggerd)
                {
                    motion_alarm_is_triggerd = FALSE;
                    Ext_SdkMotionDetectRecord_SetMode(STOP_EVENT_RECORD);
                    tuya_ipc_stop_storage(E_ALARM_CLOUD_STORAGE);
                }
            }
        }
        else
        {
            /* ak_md_get_result != 1 */
            if (Ext_InComTimer_GetSec(DEF_COM_NOT_SET_TIME,&get_res_time) >= 20)
            {
                Ext_InComTimer_GetSec(DEF_COM_SET_NEW_TIME,&get_res_time);
                total_cnt = 0;
            }
        }
        usleep(200 * 1000);
    }

    Ext_SdkMotionDetect_Exit();
    DEF_COM_EXIT_THREAD(g_ComThread_Num);
}

#if SUPPORT_AI_DETECT
extern IPC_MEDIA_INFO_S s_media_info;
OPERATE_RET TUYA_APP_Enable_AI_Detect()
{
    tuya_ipc_ai_detect_storage_init(&s_media_info);

    return OPRT_OK;
}
#endif
